package com.property.demo.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.property.demo.dto.ApiResponse;
import com.property.demo.model.Permission;
import com.property.demo.model.Role;
import com.property.demo.model.User;
import com.property.demo.model.UserRole;
import com.property.demo.repository.PermissionRepository;
import com.property.demo.repository.RoleRepository;
import com.property.demo.repository.UserRepository;
import com.property.demo.repository.UserRoleRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/satoken")
public class SaTokenController {
    
    private static final Logger logger = LoggerFactory.getLogger(SaTokenController.class);

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private RoleRepository roleRepository;
    
    @Autowired
    private PermissionRepository permissionRepository;
    
    @Autowired
    private UserRoleRepository userRoleRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody Map<String, String> loginRequest) {
        logger.info("用户登录 - 用户名: {}", loginRequest.get("username"));
        
        try {
            String username = loginRequest.get("username");
            String password = loginRequest.get("password");
            
            if (username == null || password == null) {
                logger.warn("登录失败 - 用户名或密码为空");
                return ResponseEntity.badRequest().body(new ApiResponse(false, "用户名和密码不能为空!"));
            }
            
            Optional<User> userOpt = userRepository.findByUsername(username);
            
            if (!userOpt.isPresent()) {
                logger.warn("登录失败 - 用户名不存在: {}", username);
                return ResponseEntity.badRequest().body(new ApiResponse(false, "用户名或密码错误!"));
            }
            
            User user = userOpt.get();
            
            // 调试信息 - 打印密码信息（仅用于调试，生产环境应移除）
            logger.debug("用户输入的密码: {}", password);
            logger.debug("数据库中存储的密码: {}", user.getPassword());
            logger.debug("密码匹配结果: {}", passwordEncoder.matches(password, user.getPassword()));
            
            // 验证密码
            if (!passwordEncoder.matches(password, user.getPassword())) {
                logger.warn("登录失败 - 密码错误: {}", username);
                return ResponseEntity.badRequest().body(new ApiResponse(false, "用户名或密码错误!"));
            }
            
            // 使用Sa-Token登录
            StpUtil.login(user.getId());
            String tokenValue = StpUtil.getTokenValue();
            
            // 获取用户角色
            List<UserRole> userRoles = userRoleRepository.findByUserId(user.getId());
            List<Long> roleIds = userRoles.stream()
                .map(UserRole::getRoleId)
                .collect(Collectors.toList());
            
            List<Role> roles = roleRepository.findAllById(roleIds);
            List<String> roleCodes = roles.stream()
                .map(Role::getCode)
                .collect(Collectors.toList());
            
            // 获取用户权限
            List<String> permissionCodes = StpUtil.getPermissionList(user.getId());
            
            // 构建响应
            Map<String, Object> response = new HashMap<>();
            user.setPassword(null); // 移除密码信息
            
            response.put("user", user);
            response.put("roles", roleCodes);
            response.put("permissions", permissionCodes);
            response.put("token", tokenValue);
            
            logger.info("用户登录成功 - 用户名: {}", username);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("用户登录失败 - 错误: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "登录失败: " + e.getMessage()));
        }
    }
    
    @GetMapping("/user/info")
    public ResponseEntity<?> getUserInfo() {
        try {
            // 检查是否登录
            if (!StpUtil.isLogin()) {
                return ResponseEntity.status(401).body(new ApiResponse(false, "用户未登录"));
            }
            
            // 获取当前登录用户ID
            Long userId = Long.parseLong(StpUtil.getLoginIdAsString());
            
            // 获取用户信息
            Optional<User> userOpt = userRepository.findById(userId);
            
            if (!userOpt.isPresent()) {
                return ResponseEntity.status(404).body(new ApiResponse(false, "用户不存在"));
            }
            
            User user = userOpt.get();
            user.setPassword(null); // 移除密码信息
            
            // 获取角色和权限
            List<String> roles = StpUtil.getRoleList();
            List<String> permissions = StpUtil.getPermissionList();
            
            // 构建响应
            Map<String, Object> response = new HashMap<>();
            response.put("user", user);
            response.put("roles", roles);
            response.put("permissions", permissions);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取用户信息失败 - 错误: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "获取用户信息失败: " + e.getMessage()));
        }
    }
    
    @PostMapping("/logout")
    public ResponseEntity<?> logout() {
        try {
            // 检查是否登录
            if (StpUtil.isLogin()) {
                // 登出
                StpUtil.logout();
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "登出成功");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("登出失败 - 错误: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "登出失败: " + e.getMessage()));
        }
    }
    
    @GetMapping("/checkPermission")
    public ResponseEntity<?> checkPermission(@RequestParam String permission) {
        try {
            boolean hasPermission = StpUtil.hasPermission(permission);
            
            Map<String, Object> response = new HashMap<>();
            response.put("hasPermission", hasPermission);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("检查权限失败 - 错误: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "检查权限失败: " + e.getMessage()));
        }
    }
    
    @GetMapping("/checkRole")
    public ResponseEntity<?> checkRole(@RequestParam String role) {
        try {
            boolean hasRole = StpUtil.hasRole(role);
            
            Map<String, Object> response = new HashMap<>();
            response.put("hasRole", hasRole);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("检查角色失败 - 错误: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "检查角色失败: " + e.getMessage()));
        }
    }
    
    /**
     * 重置admin用户密码
     * 注意：这个接口仅用于开发和测试环境，生产环境应该禁用或添加更严格的访问控制
     */
    @PostMapping("/reset-admin-password")
    public ResponseEntity<?> resetAdminPassword() {
        try {
            Optional<User> userOpt = userRepository.findByUsername("admin");
            
            if (!userOpt.isPresent()) {
                return ResponseEntity.status(404).body(new ApiResponse(false, "admin用户不存在"));
            }
            
            User adminUser = userOpt.get();
            
            // 重置密码为"admin123"
            adminUser.setPassword(passwordEncoder.encode("admin123"));
            userRepository.save(adminUser);
            
            logger.info("admin用户密码重置成功");
            return ResponseEntity.ok(new ApiResponse(true, "admin用户密码重置成功，新密码为: admin123"));
        } catch (Exception e) {
            logger.error("重置admin密码失败 - 错误: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "重置admin密码失败: " + e.getMessage()));
        }
    }
} 